home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / Tool Chest / Development Platforms / AppsToGo / AppsToGo.src / DTS.Lib / Help.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-18  |  5.7 KB  |  227 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        Help.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19. /* This file contains some sample code for handling dynamic balloon help.  The
  20. ** assumption here is that you used the AppsToGo program editor to add controls
  21. ** to the content of a window that have balloon help assigned to them. */
  22.  
  23.  
  24.  
  25. /*****************************************************************************/
  26.  
  27.  
  28.  
  29. #ifndef __BALLOONS__
  30. #include <Balloons.h>
  31. #endif
  32.  
  33. #ifndef __PROCESSES__
  34. #include <Processes.h>
  35. #endif
  36.  
  37. #ifndef __STRING__
  38. #include <String.h>
  39. #endif
  40.  
  41. #ifndef __STDDEF__
  42. #include <StdDef.h>
  43. #endif
  44.  
  45. #ifndef __RESOURCES__
  46. #include <Resources.h>
  47. #endif
  48.  
  49. #ifndef __UTILITIES__
  50. #include "Utilities.h"
  51. #endif
  52.  
  53. typedef struct {
  54.     short    helpVers;
  55.     long    options;
  56.     short    procID;
  57.     short    variantForTip;
  58.     short    numMessages;
  59.     short    itemSize;
  60.     short    itemType[];
  61. } hrctRec;
  62. typedef hrctRec *hrctRecPtr, **hrctRecHndl;
  63.  
  64.  
  65.  
  66. /*****************************************************************************/
  67. /*****************************************************************************/
  68.  
  69.  
  70.  
  71. #pragma segment Main
  72. Boolean    ControlBalloonHelp(WindowPtr window, Point mouseLoc)
  73. {
  74.     WindowPtr                oldPort;
  75.     ProcessSerialNumber        cpsn, fpsn;
  76.     Point                    tip;
  77.     ControlHandle            ctl, cc;
  78.     short                    i, pos, hrctID, itemID, charsUsed, strNumID, strNumIndx;
  79.     long                    ofst;
  80.     Boolean                    procsSame;
  81.     ControlStyleInfo        cinfo;
  82.     HMMessageRecord            message;
  83.     Rect                    messageRct, rct;
  84.     hrctRecHndl                hrct;
  85.     char                    *cptr;
  86.     Ptr                        ptr;
  87.     static HMMessageRecord    lastMessage;
  88.     static Rect                lastMessageRct;
  89.     static short            position[4] = {5, 6, 2, 1};
  90.  
  91.     if (gSystemVersion < 0x0700) return(false);
  92.         /* The system can't support balloons. */
  93.  
  94.     if (!window) {
  95.         if (lastMessage.hmmHelpType)
  96.             HMRemoveBalloon();
  97.         lastMessage.hmmHelpType = 0;
  98.         return(false);
  99.     }
  100.  
  101.     if (!HMGetBalloons()) {
  102.         lastMessage.hmmHelpType = 0;
  103.         return(false);
  104.     }        /* Balloons have been turned off. */
  105.  
  106.     HMGetBalloonWindow(&oldPort);
  107.     if (!oldPort)
  108.         lastMessage.hmmHelpType = 0;
  109.             /* There is no balloon currently, so there is no last message. */
  110.  
  111.     tip = mouseLoc;
  112.     GetCurrentProcess(&cpsn);
  113.     GetFrontProcess(&fpsn);
  114.     SameProcess(&cpsn, &fpsn, &procsSame);
  115.     if (!procsSame) {
  116.         lastMessage.hmmHelpType = 0;
  117.         return(false);
  118.     }        /* We aren't the front process, so leave. */
  119.  
  120.     if (!GetWRefCon(window)) {
  121.         lastMessage.hmmHelpType = 0;
  122.         return(false);
  123.     }
  124.  
  125.     GetPort(&oldPort);
  126.     SetPort(window);
  127.     GlobalToLocal(&mouseLoc);
  128.     SetPort(oldPort);
  129.  
  130.     ctl = nil;
  131.     cc  = ((WindowPeek)window)->controlList;
  132.     while (cc) {        /* Find the control that we are over. */
  133.         if (GetControlStyle(cc, &cinfo)) {
  134.             messageRct = (*cc)->contrlRect;
  135.             rct = (*(window->visRgn))->rgnBBox;
  136.             SectRect(&rct, &messageRct, &rct);
  137.             if (PtInRect(mouseLoc, &rct))
  138.                 ctl = cc;
  139.         }
  140.         cc = (*cc)->nextControl;
  141.     }
  142.  
  143.     message.hmmHelpType = 0;
  144.     if (ctl) {
  145.         messageRct = (*ctl)->contrlRect;
  146.         GetControlStyle(ctl, &cinfo);
  147.         cptr = (char *)cinfo.balloonHelp;
  148.         p2c((StringPtr)cptr);
  149.         if (!(hrctID = c2dec(cptr, &charsUsed))) {
  150.             lastMessage.hmmHelpType = 0;
  151.             return(false);
  152.         }
  153.         cptr += (charsUsed + 1);
  154.         if (!(hrct = (hrctRecHndl)GetResource('hrct', hrctID))) {
  155.             lastMessage.hmmHelpType = 0;
  156.             return(false);
  157.         }
  158.         if (!(itemID = c2dec(cptr, &charsUsed))) {
  159.             lastMessage.hmmHelpType = 0;
  160.             return(false);
  161.         }
  162.         if (itemID > (*hrct)->numMessages) {
  163.             lastMessage.hmmHelpType = 0;
  164.             return(false);
  165.         }
  166.         cptr += (charsUsed + 1);
  167.         if ((*ctl)->contrlHilite == 255)                /* If control inactive... */
  168.             if (i = c2dec(cptr, &charsUsed))    /* If alternate item for inactive... */
  169.                 itemID = i;                        /* Use alternate item. */
  170.         ofst = offsetof(hrctRec,itemSize);
  171.         for (i = 1; i < itemID; ++i) {
  172.             ptr = (Ptr)*hrct;
  173.             ofst += *(short *)(ptr + ofst);
  174.         }
  175.         ofst += sizeof(short);        /* Point to item type. */
  176.  
  177.         memset(&message, 0, sizeof(message));    /* Clean out structure for compare purposes. */
  178.         ptr = (Ptr)*hrct;
  179.         message.hmmHelpType = *(short *)(ptr + ofst);
  180.         ofst += sizeof(short);
  181.         ofst += (sizeof(Point) + sizeof(Rect));        /* Skip 'hrct' tip and rect. */
  182.         switch (message.hmmHelpType) {
  183.             case kHMStringItem:
  184.                 pcpy((StringPtr)message.u.hmmString, (StringPtr)(ptr + ofst));
  185.                 break;
  186.             case kHMPictItem:
  187.                 message.u.hmmPict = *(short *)(ptr + ofst);
  188.                 break;
  189.             case kHMStringResItem:
  190.                 strNumID = *(short *)(ptr + ofst);
  191.                 ofst += sizeof(short);
  192.                 strNumIndx = *(short *)(ptr + ofst);
  193.                 message.u.hmmStringRes.hmmResID = strNumID;
  194.                 message.u.hmmStringRes.hmmIndex = strNumIndx;
  195.                 break;
  196.             case kHMTEResItem:
  197.                 message.u.hmmTERes = *(short *)(ptr + ofst);
  198.                 break;
  199.             case kHMSTRResItem:
  200.                 message.u.hmmSTRRes = *(short *)(ptr + ofst);
  201.                 break;
  202.         }
  203.  
  204.         LocalToGlobalRect(&messageRct);
  205.         pos = (tip.v > (messageRct.top + messageRct.bottom) / 2) ? 2 : 0;
  206.         if (tip.h > (messageRct.left + messageRct.right) / 2)
  207.             ++pos;
  208.         pos = position[pos];
  209.     }
  210.  
  211.     if (message.hmmHelpType) {
  212.         if (!EqualRect(&lastMessageRct, &messageRct))
  213.             lastMessage.hmmHelpType;
  214.         if (!EqualData(&lastMessage, &message, sizeof(message))) {        /* If new balloon... */
  215.             HMShowBalloon(&message, tip, &messageRct, nil, 0, pos, kHMRegularWindow);
  216.             lastMessageRct = messageRct;
  217.             lastMessage    = message;
  218.         }
  219.         return(true);
  220.     }
  221.  
  222.     return(false);
  223. }
  224.  
  225.  
  226.  
  227.